package com.gitee.wsl.statemachine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.StateFlow

/**
 * 定义入口
 */
fun <A, State> stateMachine(scope: CoroutineScope = CoroutineScope(Dispatchers.Default + SupervisorJob()),
                                     initialState: State,
                                     configHandler:StateMachineConfig<A,State>.()->Unit ):StateMachine<A,State>{
    val config = StateMachineConfig<A,State>(initialState)
    configHandler(config)
    return StateMachineImp(config.initialState,scope,config.reducer).apply {
        config.onStateChanged?.let { observeState(it) }
        addActionHandlerMap(config.actionTriggerMap)
        addStateFlowList(config.stateFlowList)
    }
}


interface StateMachine<A,  State>:StateMachineScope< A > {

    val state : StateFlow<State>

    fun observeState(onStateChanged: StateMonitor<A,State>)

    fun getTargetStateList():List<State>

    fun getNextActionList():List<A>

    companion object
}

//fun  <A : Action, State>  CoroutineScope.stateMachine( initialState: State,configHandler:StateMachineConfig<A,State>.()->Unit ):StateMachine<A,State> = stateMachine(this,initialState,configHandler)

fun <A , State> StateMachine.Companion.create(scope: CoroutineScope = CoroutineScope(Dispatchers.Default + SupervisorJob()), initialState: State,configHandler:StateMachineConfig<A,State>.()->Unit )
        = stateMachine(scope, initialState, configHandler)



